#include "pcf8591.h"
#include "i2c.h"
#include "task.h"

static volatile pcf8591_t pcf8591_panel;

/**
 * @brief pcf8591_init
 *
 */
void pcf8591_init(void)
{
    printf("pcf8591 start read data:%bu\r\n", pcf8591_read_adc(PCF8591_ADC_CHANNEL_0));

    delay_ms(10);
}

/**
 * @brief pcf8591_adc_struct_panel
 *
 * @return *pcf8591_t
 */
pcf8591_t *pcf8591_adc_struct_panel(void)
{
    return &pcf8591_panel;
}

/**
 * @brief pcf8591_read_adc
 *
 * @param channel
 * @return read_buff
 */
uint8_t pcf8591_read_adc(uint8_t channel)
{
    uint8_t read_buff;
    channel = 0x40 | channel; /* must open output flag */

    /* Ignore the last data start */
    master_i2c_write_byte_to_device(PCF8591_ADDR, &channel, 1);
    master_i2c_read_byte_from_device(PCF8591_ADDR, &read_buff);
    /* Ignore the last data end */

    /* Get the converted data start */
    master_i2c_write_byte_to_device(PCF8591_ADDR, &channel, 1);
    master_i2c_read_byte_from_device(PCF8591_ADDR, &read_buff);
    /* Get the converted data end */

    return read_buff;
}

#if PCF8591_DAC_TASK
/**
 * @brief pcf8591_set_dac
 *
 * @param input_dac
 */
void pcf8591_set_dac(uint8_t input_dac)
{
    uint8_t dac_cmd[2];
    dac_cmd[0] = PCF8591_OUTPUT;
    dac_cmd[1] = input_dac;
    master_i2c_write_byte_to_device(PCF8591_ADDR, dac_cmd, 2);
}
#endif

#if PCF8591_ADC_TASK
/**
 * @brief pcf8591_adc_demo
 *
 */
void pcf8591_adc_demo()
{
    pcf8591_adc_struct_panel()->adc_channel_0 = pcf8591_read_adc(PCF8591_ADC_CHANNEL_0);
    pcf8591_adc_struct_panel()->adc_channel_1 = pcf8591_read_adc(PCF8591_ADC_CHANNEL_1);
    pcf8591_adc_struct_panel()->adc_channel_2 = pcf8591_read_adc(PCF8591_ADC_CHANNEL_2);
    pcf8591_adc_struct_panel()->adc_channel_3 = pcf8591_read_adc(PCF8591_ADC_CHANNEL_3);

    printf("ADC_0:%bu\r\nADC_1:%bu\r\nADC_2:%bu\r\nADC_3:%bu\r\n",
           pcf8591_adc_struct_panel()->adc_channel_0,
           pcf8591_adc_struct_panel()->adc_channel_1,
           pcf8591_adc_struct_panel()->adc_channel_2,
           pcf8591_adc_struct_panel()->adc_channel_3);
}
#endif

#if PCF8591_DAC_TASK

static uint8_t pcf8591_dac = 0;
static bit dac_fade = 0;

/**
 * @brief pcf8591_dac_demo
 *
 */
void pcf8591_dac_demo()
{
    if (pcf8591_dac == 255)
    {
        dac_fade = 1;
    }
    else if (pcf8591_dac == 0)
    {
        dac_fade = 0;
    }

    if (dac_fade)
    {
        pcf8591_dac -= 5;
    }
    else
    {
        pcf8591_dac += 5;
    }

    pcf8591_set_dac(pcf8591_dac);
}
#endif
